home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / CLESSONS.ZIP / LESSON2 < prev    next >
Text File  |  1985-12-28  |  15KB  |  395 lines

  1. .NT
  2.  A NOTE ABOUT THE LESSONS in C 
  3. .b4-24
  4. .R5C4
  5. These were written while the author was ~Ilearning~N  the language and since
  6. .R6C4
  7. they  are  ~Ifree~N ( to  copy  and/or  distribute ) there  is  a money-back
  8. .R7C4
  9. guarantee on the accuracy of each and every statement in the lessons (!)
  10. .R9C4
  11. The  ~Idisplay~N  program was written ( in C ) in order to provide a vehicle
  12. .R10C4
  13. for displaying the lessons.
  14. .R12C5
  15. .B
  16. P.J.Ponzo
  17. .B
  18. Dept. of Applied Math
  19. .B
  20. Univ. of Waterloo
  21. .B
  22. Ontario N2L 3G1
  23. .K16,30
  24. PonzoTUTOR
  25. .WNT
  26.    STRINGS 'N' THINGS   
  27.  
  28.     When we declare ~b~Ichar x;~N we tell the C compiler that ~b~Ix~N is a
  29.     ~b~Ichar~Nacter variable (so we may define ~b~Ix='Z';~N for example).
  30.  
  31.     But what if we wish to assign to ~b~Ix~N the ~Istring~N: 'hello' ?
  32.     In order to identify a string (as opposed to a single character) we write:
  33.     ~b~Ix="hello";~N  using the ~Idouble quote~N and we tell ~b~Iprintf()~N
  34.     to print ~b~Ix~N using a ~b~Is~Ntring format, ~b~I%s~N:
  35.  
  36. ~b~Imain() {~N
  37. ~b~Ichar x;~N                         declare ~b~Ichar x;~N as usual.
  38. ~b~Ix="hello";~N                      use ~Idouble quotes~N to define ~b~Ix~N.
  39. ~b~Iprintf("string x is %s",x);~N     use ~b~I%s~N to printf a ~b~Is~Ntring.
  40. ~b~I}~N
  41. .W
  42. .R20C1
  43.     The above program (when ~Icompiled~N and ~Irun~N) prints:
  44.  
  45. ~r~Istring x is hello~N
  46. .K19,60
  47.   hello!
  48. .WN
  49.  
  50.  
  51. ~b~Imain() {~N
  52. ~Vchar x;         ~N
  53. ~b~Ix="hello";~N                      use ~Idouble quotes~N to define ~b~Ix~N.
  54. ~b~Iprintf("string x is %s",x);~N     use ~b~I%s~N to printf a ~b~Is~Ntring.
  55. ~b~I}~N
  56.  
  57. .R9
  58.   ~IThis declaration of a string ~b~Ix~N~I may NOT be acceptable to your C-compiler!~N
  59. .b8-10
  60.  
  61.  
  62.  
  63. (It has the SAME format as the declaration of a single ~b~Ichar~Nacter variable!)
  64.  
  65.                             Lesson6 will explain .....
  66. .K17,32
  67. patience!
  68. .WNT
  69.   Double Quotes and Strings : Single Quotes and Characters  
  70.     Consider the following:
  71.  
  72. ~b~Imain() {~N
  73. ~b~Ichar x,y;~N                             ~b~Ix~N, ~b~Iy~N both ~b~Ichar~N.
  74. ~b~Ix="A";~N                                ~b~Ix~N is in ~Idouble~N quotes.
  75. ~b~Iy='A';~N                                ~b~Iy~N is in ~Isingle~N quotes.
  76. ~b~Iprintf("x is %s and y is %s",x,y);~N    BOTH printed as a ~b~I%s~Ntring!
  77. ~b~I}~N
  78.  
  79.     What do you think will be printed?
  80. .W
  81. .R15C1
  82. ~r~Ix is A and y is  ~N                     ~Ithe x-string is OK..but NOT the y!~N
  83. .W
  84. .R17C1
  85.     If ~b~Ix~N is defined as a string (using the ~Idouble quotes~N) and
  86.     is printed (via ~b~Iprintf()~N) using the ~b~I%s~Ntring format, then the
  87.     printout is OK. BUT if ~b~Iy~N is defined as a ~Isingle character~N (using
  88.     ~Isingle quotes~N) but is printed using the ~b~I%s~Ntring format then
  89.     ~b~Iprintf()~N gets confused (..or maybe it's ~IWE~N who are confused!).
  90.     ~w~BThis says something interesting about printf()!~N
  91. .W
  92. .N
  93.  
  94.     When we tell ~b~Iprintf()~N to print a ~b~I%s~Ntring (either ~b~Ix~N
  95.     or ~b~Iy~N) ~b~Iprintf()~N expects the ~Iaddress~N of the first
  96.     character of the string. When we ask to ~b~Iprintf()~N a ~b~I%c~Nharacter
  97.     it expects the actual character itself.
  98.  
  99.     We normally don't worry about this...just define the variable ~b~Ix~N 
  100.     as a ~Istring~N (using ~Idouble quotes~N) and ask ~b~Iprintf()~N for the
  101.     ~b~I%s~N format and - ~Iautomatically~N - the ~Iaddress~N of ~b~Ix~N is
  102.     given to ~b~Iprintf()~N and printing begins with the first character
  103.     found at that ~Iaddress~N and continues until the ~Ilast~N character 
  104.     (...and how does ~b~Iprintf()~N  know when it has reached the ~Ilast~N
  105.     character ?? ... patience ...).
  106.  
  107.     If  we define ~b~Iy~N using ~Isingle quotes~N and use the ~b~I%c~N
  108.     format in ~b~Iprintf()~N that's OK too. The C language looks after 
  109.     giving the ~Iactual character~N to ~b~Iprintf()~N (rather than the
  110.     ~Iaddress~N).
  111. .K19,60
  112. let C doit
  113. .WN
  114.  
  115. ~b~Ix="Z";~N                            ~b~Ix~N is in ~Idouble quotes~N.
  116. ~b~Iprintf("x is %s",x);~N   
  117. ~r~Ix is Z~N                            this is the printout..~IOK~N!
  118.  
  119.     If ~b~I%s~N is used in the ~b~Iprintf()~N statement, and if ~b~Ix~N is
  120.     declared and defined as a ~Istring~N, then C will look after giving to
  121.     ~b~Iprintf()~N the address where ~b~Ix~N is stored.
  122. ~b                                                                        ~N
  123.     Now consider:
  124.  
  125. ~b~Iy='Z';~N                            ~b~Iy~N is in ~Isingle quotes~N.
  126. ~b~Iprintf("y is %c",y);~N   
  127. ~r~Iy is Z~N                            this is the printout..~IOK~N!
  128.  
  129.     Here ~b~Iy~N is in ~Isingle quotes~N (hence a ~Isingle~N character) and
  130.     the ~b~I%c~N tells ~b~Iprintf()~N that the 'value' of ~b~Iy~N which it
  131.     receives is to be interpreted as the actual character itself (in this
  132.     example, the character ~b~IZ~N), so a ~r~IZ~N is (correctly) printed.
  133. .WN
  134.  
  135.  
  136.     Now consider:
  137.  
  138. ~b~Iy='Z';~N                            ~b~Iy~N is in ~Isingle quotes~N.
  139. ~b~Iprintf("y is %s",y);~N   
  140. ~r~Iy is ~N                             this is the printout ~INOT OK!~N.
  141.  
  142.     NOW ~b~Iy~N is a ~Isingle~N character (~b~IZ~N, in ~Isingle quotes~N)  but
  143.     because we asked to have it printed as a ~b~I%s~Ntring, ~b~Iprintf()~N
  144.     goes to the ~Imemory address~N given by the 'value' of ~b~Iy~N and prints
  145.     characters on the screen (according to the numbers it finds in memory)!
  146.     The 'value' given to ~b~Iprintf()~N was used as a ~w~Rpointer~N instead
  147.     of the actual character to be printed...and ~b~Iprintf()~N went to some
  148.     strange ~Iaddress~N in memory to find the ~b~I%s~Ntring to print!!
  149.  
  150.     Even if we do it right and define a string with ~Idouble quotes~N
  151.     and use ~b~I%s~N in the ~b~Iprintf()~N format (so the ~Iaddress~N of the
  152.     beginning of our string is passed to ~b~Iprintf()~N) ~ITHEN~N....
  153.     ~w~Bhow does printf() know when it has come to the end of our string??~N
  154. .WNT
  155.  ..how does a string end?  
  156.  
  157.     When we say ~b~Ix="hello";~N the C compiler will put the correct 'values'
  158.     for the characters ~b~Ih~N, ~b~Ie~N, ~b~Il~N, ~b~Il~N, ~b~Io~N into memory
  159.     and add, ~Iat the end~N (after the ~b~Io~N) the 'value' ~I0~N.
  160.     It is this 'value' ~I0~N which signals the end of the string!
  161.  
  162.     NOTE: Every character such as ~b~Ia~N, ~b~Ib~N, ~b~IZ~N, ~b~I{~N, etc.
  163.     has a certain 'value' (or 'number') associated with it. In ~IASCII~N
  164.     (~IA~Nmerican ~IS~Ntandard ~IC~Node for ~II~Nnformation ~II~Nnterchange)
  165.     the 'value' or 'number' associated with ~b~IA~N is ~I65~N (in decimal) and
  166.     the 'value' or 'number' associated with ~b~I0~N is ~I48~N (in decimal).
  167.     Notice that it is NOT the 'number' ~I0~N which is associated with the
  168.     character ~b~I0~N but rather the 'number' ~I48~N! ~ISO~N...the ~I0~N which
  169.     terminates strings cannot be confused with the character ~b~I 0~N.
  170.     After all, the string may, in fact, be defined by: ~b~Ix="10"~N which
  171.     will be stored in memory as the two 'numbers' associated with the two
  172.     characters ~b~I1~N and ~b~I0~N (namely the two 'numbers' ~I49~N ~I48~N)
  173.     followed by the terminating number ~I0~N
  174. .WN
  175.  
  176.  
  177.  
  178.  
  179.  
  180.     It is possible to define a string by defining an ~Iarray of single~N
  181.     ~Icharacters~N. Although we will talk (later) about ~Iarrays~N, now is
  182.     an opportune time to talk briefly about such a definition of a string
  183.     because, in this instance, we must ~Idefine the last single character~N
  184.     ~Iin the array as the special terminating character, 0~N.
  185. .K18,30
  186. special 0
  187. .WNT
  188.   ...just one word about 'string arrays'  
  189.  
  190. ~b~Ichar x[10];~N                 defines an ~Iarray~N of ~b~I10~N elements.
  191. ~b~Ix[0]='A';~N                   the first element is the character ~b~IA~N.
  192. ~b~Ix[1]='b';~N                   the second element is the character ~b~Ib~N.
  193. ~b~Ix[2]='{';~N                   the third element is the character ~b~I{~N.
  194. ~b~Ix[3]='\0';~N                  the last element is the 'number' ~I0~N!!!!
  195. ~b~Iprintf("the string is %s",x);~N    print the string, up to the ~I0~N.
  196.  
  197.     ...and the printout would be: ~r~Ithe string is Ab{~N
  198.  
  199.    ~w~B                                                           ~N
  200.    ~w~B but note the strange way we had to define the terminating ~N
  201.    ~w~B element  so that C would  recognize it as the 'number' 0  ~N
  202.    ~w~B and not the 'character' 0 ... we used  ~b~W\0~w~B  inside  single ~N
  203.    ~w~B quotes in the statement: ~b~Wx[3]='\0';~w~B                       ~N
  204.    ~w~B                                                           ~N
  205. .WNT
  206.   Other special characters like \0  
  207.  
  208.     In order to define the special character ~I0~N which terminates a string
  209.     we referred to it as ~b~I\0~N. The ~Ibackslash~N ~b~I\~N notifies C that
  210.     the VERY NEXT CHARACTER is to be interpreted in a SPECIAL manner. (We've
  211.     seen this kind of thing before: ~b~I%~N means the NEXT CHARACTER(s)
  212.     is 'special' in a ~b~Iprintf()~N format....as in ~b~I%s~N).
  213.  
  214.     There are other ~b~I\character~N combinations in C. In each case they 
  215.     are used to define a character which cannot (normally) be typed into
  216.     your text. For example you may have noticed that the statements:
  217.  
  218. ~b~Ichar x,y;~N
  219. ~b~Ix="Z"; y='Z';~N
  220. ~b~Iprintf("x is %s y is %c",x,y);~N
  221.  
  222.     will print: 
  223.  
  224. ~r~Ix is Z y is Z~N 
  225. .K19,60
  226. ZZZZZZZZZZ
  227. .WN
  228.  
  229.  
  230.  
  231.  
  232.     Now suppose we wanted to print:~r~Ix is Z~N and ~r~Iy is Z~N    
  233.     on two separate lines! Then we tell ~b~Iprintf()~N to print a 'special'
  234.     character, ~b~I\n~N, meaning a ~b~In~New line:
  235.  
  236. ~b~Ichar x,y;~N
  237. ~b~Ix="Z"; y='Z';~N
  238. ~b~Iprintf("x is %s ~N~V\n~b~I~W y is %c",x,y);~N   notice the ~V\n~N!
  239.  
  240. ~r~Ix is Z ~N           this is the printout,
  241. ~r~I y is Z~N           notice the spaces.
  242. .K19,60
  243. \n=newline
  244. .WNT
  245.   SPECIAL \CHARACTERS  
  246.  
  247.     We have the following 'special' characters:
  248.  
  249. ~b~I\n~N      the ~In~New line.
  250. ~b~I\t~N      the ~It~Nab character.
  251. ~b~I\0~N      the ~I0~N terminator (NULL character), ASCII 'value' ~I0~N.
  252. ~b~I\b~N      the ~Ib~Nackspace.
  253. ~b~I\"~N      the double quote.
  254. ~b~I\\~N      the backslash character.
  255.  
  256.     What would the following print?
  257.  
  258. ~b~Iint age;~N
  259. ~b~Iage=100;~N
  260. ~b~Iprintf("\"Sam\" is %d years old\t\ttoday",age);~N
  261. .W
  262. .R21C1
  263. ~r~I"Sam" is 100 years old          today~N          Notice the ~Iquotes~N
  264.                                                      and the ~Itabs~N.
  265. .R23C1
  266. ~b~Iprintf("~N~V\"~b~I~WSam~N~V\"~b~I~W is %d years old~N~V\t\t~b~I~Wtoday",age);~N
  267. .WNT
  268.   Other 'format' info you can give to printf()  
  269.     We've seen the ~b~I%d~N (for ~b~Id~Necimal number printouts) and we've
  270.     seen ~b~I%f~N (for ~b~If~Nloating point numbers), and ~b~I%c~N and ~b~I%s~N
  271.     for ~b~Ic~Nharacters and ~b~Is~Ntrings, but we have also ~b~I%o~N (for 
  272.     ~b~Io~Nctal numbers) and ~b~I%x~N (for he~b~Ix~Nadecimal numbers) and 
  273.     ~b~I%e~N (numbers ~b~Ie~Nxponential format, such as ~r~I-7.001100E+03~N).
  274.     In each case you may qualify the above ~Iformat~N instruction with a
  275.     ~Ifield width~N specification, such as:
  276. .w
  277. ~b~Iint a=123;printf("%6d",a);~N         ~V   123~N
  278.  
  279. ~b~Ifloat b=123;printf("%6.3f",b);~N     ~V123.000~N
  280.  
  281. ~b~Ichar c='1';printf("%6c",c);~N        ~V     1~N
  282.  
  283. ~b~Ichar d="123";printf("%6s",d);~N      ~V   123~N
  284.  
  285. ~b~Iint e=123;printf("%6o",e);~N         ~V   173~N
  286.  
  287. ~b~Ifloat f=123;printf("%6e",f);~N       ~V1.230000E+02~N
  288.  
  289. ~b~Iint g=123;printf("%6x",g);~N         ~V    7B~N      in HEXADECIMAL
  290. .K16,60
  291. 173=octal
  292. .WNT
  293.   good form .. bad form  
  294.  
  295. .K5,60
  296. bad form?!
  297.  
  298.  
  299.     You may have noticed, in the compound statement:
  300.  
  301. ~b~Ifloat b=123;printf("%6.3f",b);~N     ~V123.000~N
  302.  
  303.     that we declared ~b~Ib~N to be a ~b~Ifloat~N and, ~Iat the same time~N, we
  304.     defined it to be ~b~I123~N (as in ~b~Ifloat b=123;~N). ~IThat's legal~N.
  305.  
  306.     BUT we also added ~b~Iprintf("%6.3f",b);~N ~Ion the same line~N. That's
  307.     considered ~Ibad form~N (...but sure convenient if you want to see as
  308.     much of your program as possible on a 25-line screen!)
  309.  
  310.     Note: for ~b~Ib=123~N, ~b~I6.~N~V3~b~I~Wf~N doesn't provide enough ~Ifield~N
  311.     ~Iwidth~N (if we want ~V3~N decimal places) so ~b~Iprintf()~N expands
  312.     the field width to ~b~I7~N (as required to accommodate ~V123.000~N).
  313. .WN
  314.  
  315.     You will also have noticed that the statement:
  316.  
  317. ~b~Ichar d="123";printf("%6s",d);~N      ~V   123~N
  318.  
  319.     ~Iright justified~N the ~r~I123~N in a ~Ifield width~N of 6. You may
  320.     ask ~b~Iprintf()~N to ~Ileft-justify~N the ~r~I123~N by specifying:
  321.  
  322. ~b~Ichar d="123";printf("%-6s",d);~N     ~V123   ~N
  323.  
  324.     (Notice the format specification ~b~I%-6s~N with ~b~I-~N meaning
  325.      ~Ileft-justify~N).
  326.  
  327.     If ~b~Ib="1234567";~N then (as expected) ~b~Iprintf()~N will make the
  328.     ~Ifield width~N ~b~I7~N (to accommodate ~r~I1234567~N)...even if we
  329.     asked for ~b~I%6s~N! If you ~IREALLY MEAN 6~N (and want to cut off the 
  330.     string) then use the specification: ~b~I%.6s~N
  331.  
  332. ~b~Ichar d="1234567";printf("%.6s",d);~N     ~V123456~N  note the ~b~I.6~N.
  333. .WNT
  334.     A note on format specifications   
  335.  
  336.  
  337.  
  338.     If ~b~Is~N has been declared and defined as a string: ~b~Is="I'm a string"~N
  339.     ( with 12 characters ) then we may select any number of characters and
  340.     print then in a specified field width:
  341.  
  342. ~b~Iprintf("%s",s);~N         gives   ~VI'm a string~N
  343.  
  344. ~b~Iprintf("%20.12s",s);~N    gives   ~V        I'm a string~N
  345.  
  346. ~b~Iprintf("%-20.12s",s);~N   gives   ~VI'm a string        ~N
  347.  
  348. ~b~Iprintf("%20.10s",s);~N    gives   ~V          I'm a stri~N
  349.  
  350. ~b~Iprintf("%-20.10s",s);~N   gives   ~VI'm a stri          ~N
  351.                                field width = 20 
  352.            print only 10 characters
  353. .WNT
  354.     More notes on format specifications    
  355.  
  356.     If ~b~Ix~N has been declared and defined as an int: ~b~Ix=123~N
  357.     then we have:
  358.  
  359. ~b~Iprintf("%d",x);~N        gives   ~V123~N
  360.  
  361. ~b~Iprintf("%10d",x);~N      gives   ~V       123~N
  362.  
  363. ~b~Iprintf("%-10d",x);~N     gives   ~V123       ~N
  364.  
  365. ~b~Iprintf("%010d",x);~N     gives   ~V0000000123~N
  366.  
  367. ~b~Iprintf("%010x",x);~N     gives   ~V000000007B~N   in HEXADECIMAL
  368.                               width=10
  369.        this ~I0~N pads with 0's
  370. .WNT
  371.     ...and some final notes on format     
  372.  
  373.     If ~b~Ix~N has been declared and defined as an float: ~b~Ix=123.456~N
  374.     then we have:
  375.  
  376. ~b~Iprintf("%f",x);~N        gives   ~V123.456000~N
  377.  
  378. ~b~Iprintf("%10.4f",x);~N    gives   ~V  123.4560~N
  379.  
  380. ~b~Iprintf("%-10.2f",x);~N   gives   ~V123.46    ~N
  381. .WN
  382.  
  383.  
  384.  
  385.  
  386. .T
  387.     That's all folks!    
  388.  
  389. .K16,32
  390. au revoir!
  391.  
  392. .q
  393.  
  394.  
  395.